import { ref, computed, reactive } from 'vue'

// 加载状态键枚举
export enum LoadingKeys {
  // 全局加载
  GLOBAL = 'global',
  
  // 认证相关
  LOGIN = 'login',
  LOGOUT = 'logout',
  REFRESH_TOKEN = 'refresh_token',
  
  // 消息相关
  LOAD_MESSAGES = 'load_messages',
  LOAD_MORE_MESSAGES = 'load_more_messages',
  SEND_MESSAGE = 'send_message',
  MARK_MESSAGE_READ = 'mark_message_read',
  
  // 会话相关
  LOAD_CONVERSATIONS = 'load_conversations',
  CREATE_CONVERSATION = 'create_conversation',
  
  // 好友相关
  LOAD_FRIENDS = 'load_friends',
  SEARCH_FRIENDS = 'search_friends',
  ADD_FRIEND = 'add_friend',
  REMOVE_FRIEND = 'remove_friend',
  
  // 连接相关
  CONNECT = 'connect',
  RECONNECT = 'reconnect',
  SYNC_OFFLINE_MESSAGES = 'sync_offline_messages',
  
  // 文件上传
  UPLOAD_IMAGE = 'upload_image',
  UPLOAD_FILE = 'upload_file',
  UPLOAD_VOICE = 'upload_voice'
}

// 加载状态接口
export interface LoadingState {
  isLoading: boolean
  message?: string
  progress?: number
  startTime?: number
  timeout?: number
}

// 加载配置接口
export interface LoadingConfig {
  message?: string
  timeout?: number
  showProgress?: boolean
  silent?: boolean
}

// 加载管理器类
class LoadingManager {
  private loadingStates = reactive<Record<string, LoadingState>>({})
  private loadingQueue: string[] = []
  private timeouts = new Map<string, NodeJS.Timeout>()
  private listeners: Array<(key: string, state: LoadingState) => void> = []

  constructor() {
    // 初始化所有预定义的加载状态
    Object.values(LoadingKeys).forEach(key => {
      this.loadingStates[key] = {
        isLoading: false
      }
    })
  }

  /**
   * 开始加载
   */
  start(key: string, config?: LoadingConfig | string): void {
    const loadingConfig: LoadingConfig = typeof config === 'string' 
      ? { message: config }
      : config || {}

    const state: LoadingState = {
      isLoading: true,
      message: loadingConfig.message,
      progress: loadingConfig.showProgress ? 0 : undefined,
      startTime: Date.now(),
      timeout: loadingConfig.timeout
    }

    this.loadingStates[key] = state

    // 添加到队列
    if (!this.loadingQueue.includes(key)) {
      this.loadingQueue.push(key)
    }

    // 设置超时
    if (loadingConfig.timeout) {
      this.setLoadingTimeout(key, loadingConfig.timeout)
    }

    // 通知监听器
    this.notifyListeners(key, state)

    console.log(`Loading started: ${key}`, state)
  }

  /**
   * 停止加载
   */
  stop(key: string): void {
    if (!this.loadingStates[key]) {
      return
    }

    const state = this.loadingStates[key]
    const duration = state.startTime ? Date.now() - state.startTime : 0

    this.loadingStates[key] = {
      ...state,
      isLoading: false,
      progress: undefined
    }

    // 从队列中移除
    const index = this.loadingQueue.indexOf(key)
    if (index > -1) {
      this.loadingQueue.splice(index, 1)
    }

    // 清除超时
    this.clearLoadingTimeout(key)

    // 通知监听器
    this.notifyListeners(key, this.loadingStates[key])

    console.log(`Loading stopped: ${key} (${duration}ms)`)
  }

  /**
   * 更新加载进度
   */
  updateProgress(key: string, progress: number, message?: string): void {
    if (!this.loadingStates[key] || !this.loadingStates[key].isLoading) {
      return
    }

    this.loadingStates[key] = {
      ...this.loadingStates[key],
      progress: Math.max(0, Math.min(100, progress)),
      message: message || this.loadingStates[key].message
    }

    // 通知监听器
    this.notifyListeners(key, this.loadingStates[key])
  }

  /**
   * 更新加载消息
   */
  updateMessage(key: string, message: string): void {
    if (!this.loadingStates[key]) {
      return
    }

    this.loadingStates[key] = {
      ...this.loadingStates[key],
      message
    }

    // 通知监听器
    this.notifyListeners(key, this.loadingStates[key])
  }

  /**
   * 检查是否正在加载
   */
  isLoading(key: string): boolean {
    return this.loadingStates[key]?.isLoading || false
  }

  /**
   * 获取加载状态
   */
  getState(key: string): LoadingState | null {
    return this.loadingStates[key] || null
  }

  /**
   * 获取所有加载状态
   */
  getAllStates(): Record<string, LoadingState> {
    return { ...this.loadingStates }
  }

  /**
   * 检查是否有任何加载中的状态
   */
  hasAnyLoading(): boolean {
    return this.loadingQueue.length > 0
  }

  /**
   * 获取当前加载队列
   */
  getLoadingQueue(): string[] {
    return [...this.loadingQueue]
  }

  /**
   * 停止所有加载
   */
  stopAll(): void {
    const loadingKeys = [...this.loadingQueue]
    loadingKeys.forEach(key => this.stop(key))
  }

  /**
   * 添加状态监听器
   */
  addListener(listener: (key: string, state: LoadingState) => void): () => void {
    this.listeners.push(listener)
    return () => {
      const index = this.listeners.indexOf(listener)
      if (index > -1) {
        this.listeners.splice(index, 1)
      }
    }
  }

  /**
   * 设置加载超时
   */
  private setLoadingTimeout(key: string, timeout: number): void {
    this.clearLoadingTimeout(key)
    
    const timeoutId = setTimeout(() => {
      console.warn(`Loading timeout: ${key} (${timeout}ms)`)
      this.stop(key)
    }, timeout)
    
    this.timeouts.set(key, timeoutId)
  }

  /**
   * 清除加载超时
   */
  private clearLoadingTimeout(key: string): void {
    const timeoutId = this.timeouts.get(key)
    if (timeoutId) {
      clearTimeout(timeoutId)
      this.timeouts.delete(key)
    }
  }

  /**
   * 通知监听器
   */
  private notifyListeners(key: string, state: LoadingState): void {
    this.listeners.forEach(listener => {
      try {
        listener(key, state)
      } catch (error) {
        console.error('Error in loading state listener:', error)
      }
    })
  }

  /**
   * 包装异步操作
   */
  async wrap<T>(
    key: string,
    operation: () => Promise<T>,
    config?: LoadingConfig
  ): Promise<T> {
    try {
      this.start(key, config)
      const result = await operation()
      return result
    } finally {
      this.stop(key)
    }
  }

  /**
   * 包装异步操作（带进度）
   */
  async wrapWithProgress<T>(
    key: string,
    operation: (updateProgress: (progress: number, message?: string) => void) => Promise<T>,
    config?: LoadingConfig
  ): Promise<T> {
    try {
      this.start(key, { ...config, showProgress: true })
      
      const updateProgress = (progress: number, message?: string) => {
        this.updateProgress(key, progress, message)
      }
      
      const result = await operation(updateProgress)
      return result
    } finally {
      this.stop(key)
    }
  }

  /**
   * 创建响应式加载状态
   */
  createReactiveState(key: string) {
    return computed(() => this.loadingStates[key] || { isLoading: false })
  }

  /**
   * 创建响应式加载检查
   */
  createReactiveCheck(key: string) {
    return computed(() => this.isLoading(key))
  }

  /**
   * 批量操作
   */
  batch(operations: Array<{ key: string; config?: LoadingConfig }>) {
    return {
      start: () => {
        operations.forEach(({ key, config }) => this.start(key, config))
      },
      stop: () => {
        operations.forEach(({ key }) => this.stop(key))
      }
    }
  }

  /**
   * 获取加载统计信息
   */
  getStats() {
    const states = Object.values(this.loadingStates)
    const loadingStates = states.filter(state => state.isLoading)
    
    return {
      total: states.length,
      loading: loadingStates.length,
      idle: states.length - loadingStates.length,
      queue: this.loadingQueue.length,
      averageLoadingTime: this.calculateAverageLoadingTime(loadingStates)
    }
  }

  /**
   * 计算平均加载时间
   */
  private calculateAverageLoadingTime(loadingStates: LoadingState[]): number {
    if (loadingStates.length === 0) return 0
    
    const now = Date.now()
    const totalTime = loadingStates.reduce((sum, state) => {
      return sum + (state.startTime ? now - state.startTime : 0)
    }, 0)
    
    return Math.round(totalTime / loadingStates.length)
  }

  /**
   * 清理过期状态
   */
  cleanup(maxAge: number = 5 * 60 * 1000): void {
    const now = Date.now()
    
    Object.keys(this.loadingStates).forEach(key => {
      const state = this.loadingStates[key]
      if (!state.isLoading && state.startTime && now - state.startTime > maxAge) {
        delete this.loadingStates[key]
      }
    })
  }
}

// 创建全局加载管理器实例
export const loadingManager = new LoadingManager()

// 便捷函数
export const startLoading = (key: string, config?: LoadingConfig | string) => {
  loadingManager.start(key, config)
}

export const stopLoading = (key: string) => {
  loadingManager.stop(key)
}

export const isLoading = (key: string): boolean => {
  return loadingManager.isLoading(key)
}

export const updateLoadingProgress = (key: string, progress: number, message?: string) => {
  loadingManager.updateProgress(key, progress, message)
}

export const updateLoadingMessage = (key: string, message: string) => {
  loadingManager.updateMessage(key, message)
}

export const wrapWithLoading = <T>(
  key: string,
  operation: () => Promise<T>,
  config?: LoadingConfig
): Promise<T> => {
  return loadingManager.wrap(key, operation, config)
}

export const wrapWithProgressLoading = <T>(
  key: string,
  operation: (updateProgress: (progress: number, message?: string) => void) => Promise<T>,
  config?: LoadingConfig
): Promise<T> => {
  return loadingManager.wrapWithProgress(key, operation, config)
}

// 创建响应式加载状态 hook
export const useLoading = (key: string) => {
  const state = loadingManager.createReactiveState(key)
  const isLoadingState = loadingManager.createReactiveCheck(key)
  
  return {
    state,
    isLoading: isLoadingState,
    start: (config?: LoadingConfig | string) => loadingManager.start(key, config),
    stop: () => loadingManager.stop(key),
    updateProgress: (progress: number, message?: string) => 
      loadingManager.updateProgress(key, progress, message),
    updateMessage: (message: string) => loadingManager.updateMessage(key, message)
  }
}

// 定期清理过期状态
setInterval(() => {
  loadingManager.cleanup()
}, 60000) // 每分钟清理一次